package com.wedu.modules.dss.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.wedu.common.utils.PageUtils;
import com.wedu.common.utils.Query;
import com.wedu.modules.dss.dao.DeviceDao;
import com.wedu.modules.dss.dao.OperationStatusDao;
import com.wedu.modules.dss.entity.dto.OperationSaveDTO;
import com.wedu.modules.dss.entity.DeviceEntity;
import com.wedu.modules.dss.entity.OperationStatusEntity;
import com.wedu.modules.dss.entity.Vo.ErrorManageEntityVo;
import com.wedu.modules.dss.entity.Vo.OperationStatusEntityVo;
import com.wedu.modules.dss.service.DssOperationStatusService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service("DssOperationStatusService")
public class OperationStatusImpl extends MPJBaseServiceImpl<OperationStatusDao, OperationStatusEntity> implements DssOperationStatusService {
@Autowired
    private OperationStatusDao operationStatusDao;
@Autowired
    private DeviceDao deviceDao;
    @Override
    public PageUtils queryOperationStatus(Map<String,Object> params) {
        String deviceId = (String)params.get("deviceId");
        String devicename = (String)params.get("name");
      //根据链表查询deviceId相等，查询出deviceId，deviceName，lightStatus，lightStartTime，lightEndTime
        MPJLambdaWrapper<OperationStatusEntity> wrapper = new MPJLambdaWrapper<>();
        wrapper.select(OperationStatusEntity::getLightStatus,OperationStatusEntity::getLightStartTime,OperationStatusEntity::getLightEndTime)
                .select(DeviceEntity::getDeviceName,DeviceEntity::getId,DeviceEntity::getDeviceId)
                //查询DeviceEntity的is_deleted 为0
                .eq(DeviceEntity::getDeleted,0)
                .leftJoin(DeviceEntity.class, DeviceEntity::getId, OperationStatusEntity::getDeviceId)
                .like(StringUtils.isNotBlank(devicename),DeviceEntity::getDeviceName,devicename)
                .like(StringUtils.isNotBlank(deviceId),DeviceEntity::getDeviceId,deviceId)
                //结束时间为null的数据
                .isNull(OperationStatusEntity::getLightEndTime)
                .orderByAsc(OperationStatusEntity::getDeviceId);
      IPage<OperationStatusEntityVo> page = operationStatusDao.selectJoinPage(
                new Query<OperationStatusEntityVo>().getPage(params),
                OperationStatusEntityVo.class,
                wrapper
        );
        return new PageUtils(page);
    }



    @Override
    public void saveByUser(String deviceId, Integer lightStatus) {
        //根据传进来的设备id从dss_operation_status表中到当前的在数据库中结束时间未null的一条数据
        QueryWrapper<DeviceEntity> wrapper1 =  new QueryWrapper<>();
        wrapper1.select("id")
                .eq("device_id",deviceId);
        DeviceEntity deviceEntity = deviceDao.selectOne(wrapper1);
        long mainId = deviceEntity.getId();
        QueryWrapper<OperationStatusEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("device_id",mainId)
                .isNull("light_over");
        OperationStatusEntity operationStatusEntity = operationStatusDao.selectOne(wrapper);
        if(operationStatusEntity.getLightStatus() != lightStatus) {

                operationStatusEntity.setLightEndTime(new Date());
                // 调用更新方法
                this.updateById(operationStatusEntity);

            //修改了上一条数据，并且再插入一条更改了灯状态的数据
            OperationStatusEntity operationStatusEntity1 = new OperationStatusEntity();

            operationStatusEntity1.setDeviceId(mainId);
            operationStatusEntity1.setLightStatus(lightStatus);
            operationStatusEntity1.setLightStartTime(new Date());
            this.save(operationStatusEntity1);
        }

    }

    @Override
    public void batchSaveByUser(List<OperationSaveDTO> operationList) {
        for (OperationSaveDTO dto : operationList) {
           String deviceId = dto.getDeviceId();
            Integer lightStatus = dto.getLightStatus();
            saveByUser(deviceId, lightStatus);
        }
    }

    @Override
    public PageUtils queryErrorManage(Map<String, Object> params) {
        String devicename = (String) params.get("name");
        String deviceId = (String) params.get("deviceId");
        MPJLambdaWrapper<OperationStatusEntity> wrapper = new MPJLambdaWrapper<>();
        wrapper.select(OperationStatusEntity::getLightStatus, OperationStatusEntity::getLightStartTime, OperationStatusEntity::getLightEndTime)
                .select(DeviceEntity::getDeviceName,DeviceEntity::getDeviceId,DeviceEntity::getId)
                .eq(DeviceEntity::getDeleted, 0)
                .eq(OperationStatusEntity::getLightStatus, -1)
                .like(StringUtils.isNotBlank(devicename), DeviceEntity::getDeviceName, devicename)
                .like(StringUtils.isNotBlank(deviceId), DeviceEntity::getDeviceId, deviceId)
                .leftJoin(DeviceEntity.class, DeviceEntity::getId, OperationStatusEntity::getDeviceId);
        List<OperationStatusEntityVo> list = operationStatusDao.selectJoinList(OperationStatusEntityVo.class, wrapper);
        List<ErrorManageEntityVo> errorManageEntities = new ArrayList<>();
        //获取到dss_device_information中的所有deviceId
        HashSet<Long> listIds =new HashSet<>();
        for (OperationStatusEntityVo operationStatusEntityVo : list){
            listIds.add(operationStatusEntityVo.getId());
        }
        for (long listId : listIds) {
            ErrorManageEntityVo errorManageEntityVo =new ErrorManageEntityVo();
            int alarmCount = 0;
            long errorTime = 0;
            QueryWrapper<DeviceEntity> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("id",listId);
            DeviceEntity deviceEntity = deviceDao.selectOne(wrapper1);
            errorManageEntityVo.setDeviceId(deviceEntity.getDeviceId());
            for (OperationStatusEntityVo operationStatusEntityVo : list) {
                if(listId==operationStatusEntityVo.getId()){
                    alarmCount++;
                    if(operationStatusEntityVo.getLightEndTime()!=null) {
                        errorTime = errorTime + (operationStatusEntityVo.getLightEndTime().getTime() - operationStatusEntityVo.getLightStartTime().getTime());
                    }else
                    {
                        errorTime = errorTime + (new Date().getTime() - operationStatusEntityVo.getLightStartTime().getTime());
                    }
                    errorManageEntityVo.setDeviceName(operationStatusEntityVo.getDeviceName());
                }
            }
            errorManageEntityVo.setAlarmCount(alarmCount);
            String formattedTime = formatErrorTime(errorTime);
            errorManageEntityVo.setErrorTime(formattedTime);
            errorManageEntities.add(errorManageEntityVo);
        }

        IPage<OperationStatusEntity> page = this.page(new Query<OperationStatusEntity>().getPage(params));
        int current = (int) page.getCurrent();
        int size = (int) page.getSize();
        int start = (current - 1) * size;
        int end = Math.min(start + size, errorManageEntities.size());
        List<ErrorManageEntityVo> paginatedList = errorManageEntities.subList(start, end);
        IPage<ErrorManageEntityVo> errorManageEntityVoIPage = new Page<>();
        errorManageEntityVoIPage.setTotal(errorManageEntities.size());
        errorManageEntityVoIPage.setSize(size);
        errorManageEntityVoIPage.setPages(page.getPages());
        errorManageEntityVoIPage.setRecords(paginatedList);
        errorManageEntityVoIPage.setCurrent(current);
        return new PageUtils(errorManageEntityVoIPage);

    }

    private String formatErrorTime(long errorTime) {
        // 一天的毫秒数
        long oneDayMillis = 24 * 60 * 60 * 1000;
        // 一小时的毫秒数
        long oneHourMillis = 60 * 60 * 1000;
        // 一分钟的毫秒数
        long oneMinuteMillis = 60 * 1000;

        // 计算天数
        long days = errorTime / oneDayMillis;
        errorTime %= oneDayMillis;

        // 计算小时数
        long hours = errorTime / oneHourMillis;
        errorTime %= oneHourMillis;

        // 计算分钟数
        long minutes = errorTime / oneMinuteMillis;
        // 计算秒数
        long seconds = errorTime % oneMinuteMillis / 1000;

        StringBuilder timeStr = new StringBuilder();
        if (days > 0) timeStr.append(days).append("天");
        if (hours > 0) timeStr.append(hours).append("时");
        if (minutes > 0) timeStr.append(minutes).append("分");
        if (seconds > 0) timeStr.append(seconds).append("秒");

        return timeStr.length() > 0 ? timeStr.toString() : "0秒";
    }

}



